import threading
import time

SLEEP_SECS = 5

class ThreadPoolMgr(object):
    """
    provides the throttle for running multiple 
    threads for commands.
    """
    def __init__(self,maxthreads=10,snooze=SLEEP_SECS):
        "Set up thread pool"
        self._max = maxthreads
        self._running = []
        self._lock = threading.Lock()
        self._snooze = snooze
        
        #create slots for threads
        for x in range(maxthreads):
            self._running.append(None)    

    #-------------------------
    # properties
    def _getSnooze(self):
        return self._snooze
    def _setSnooze(self,secs):
        self._snooze = secs
    snooze = property(_getSnooze,_setSnooze)
    
    #-------------------------
    # API
    def run(self,thrd):
        "queue up the command"
        # find a slot for thread
        slot = self._findSlot(thrd)
        
        # start thread
        thrd.start()
    
    #-------------------------
    # implementation
    def _findSlot(self,thrd):
        "find a free slot to run the command"
        rv = -1
        x = 0
        while 1:
            # roll through slots looking for
            # empty slots or finished commands.
            # get the lock
            while not self._lock.acquire(False):
                time.sleep(self.snooze)
            try:
                while rv < 0 and x < self._max:
                        t = self._running[x]
                        if not t or t.status == 3:
                            rv = x
                        else:
                            x += 1
                if rv < 0:
                    # missed
                    x = 0 
                else:
                    # give up the slot
                    self._running[x] = thrd
                     
                    # return index
                    return rv
            finally:
                # always release lock
                self._lock.release()
            
            # wait 10 then do it again
            time.sleep(self.snooze)
        
